/*****************************************************************************
文 件 名: config.c
描    述: 1.6 代墒情站 系统配置模块
作    者: 武玉峰
版    本: 1.0
完成日期: 2016.8.19
最后修改:
修改历史: 
*****************************************************************************/
#ifdef SOIL_MOISTURE_STATION_1_6 
#include <string.h>
#include "config.h"
#include "usart.h"
#include "rtc.h"
#include "stmflash.h"
#include "24cxx.h"
#include "wdg.h"
#include "atcommand.h"
#include "gpio.h"
#include "gprs.h"

//工作模式
extern u8        _WorkPattern;
 

//串口3的数据接收缓存，为节省内存，该缓存会被临时用于其它用途
u8        _UART3Buffer[RECEIVED_BUFFER_SIZE];
//串口3已接收到的数据的最后一个字节在数据缓存中的索引
u16       _UART3BufferPosition;

//sim900信号强度
extern u8         _SignalIntensity;
//sim900IMEI号
extern u8         _IMEI[16];
//RTC日历
extern CalendarType _calendar;

//串口3如果收到这个字符串，会进入配置模式
u8 	       const   _QueryStr[] = "Are you ready?\r\n";
//进入配置模式字符串索引
u16       _QueryStrIndex = 0;
//每个配置命令应当收到的字节数
u16       _CFGPHopedByteCounts = 0;
//是否接收到配置命令
u8        _CommandReceived;
//离线记录个数仍然存储在24c256中
u16       _RecordCount = 0;

Config _Config;


/*
 *  以下变量为用户配置 
 */
 

 




/*************************************************
函数名称: ConfigProcess
功    能: USART3 中断处理程序调用此函数
参    数: USART3中断收到的一个字节 
返 回 值: 无
*************************************************/
void ConfigProcess(u8 Res)
{
	//0-初始模式 1-配置模式 2-工作模式
        if(_WorkPattern == 2)
        {
            //工作模式
           
            if(_QueryStr[_QueryStrIndex] == Res)
            {
                ++_QueryStrIndex;
            }
            else
            {
                _QueryStrIndex = 0;

            }
            //char code _QueryStr[]="Are you ready?\r\n";
            if(_QueryStrIndex == 16)
            {
                _WorkPattern = 1;
                memset(_UART3Buffer, '\0', sizeof(_UART3Buffer));
                _UART3BufferPosition = 0;
            }


        }
        else if(_WorkPattern == 0)
        {
            //初始模式
            if(_QueryStr[_QueryStrIndex] == Res)
            {
                ++_QueryStrIndex;
            }
            else
            {
                _QueryStrIndex = 0;

            }
            //char code _QueryStr[]="Are you ready?\r\n";
            if(_QueryStrIndex == 16)
            {
                _WorkPattern = 1;
                memset(_UART3Buffer, '\0', sizeof(_UART3Buffer));
                _UART3BufferPosition = 0;
            }
        }
        else if(_WorkPattern == 1)
        {
            //配置模式
            if(_CommandReceived == 0)
            {
                _UART3Buffer[_UART3BufferPosition] = Res;

                if(_UART3BufferPosition == 0)
                {


                    switch(Res)
                    {
                    case 0xA0://写入所有配置
                        _CFGPHopedByteCounts = 170;
                        break;
                    case 0xA1://读取所有配置
                    case 0xA2://清除数据
                    case 0xA4://重置
										case 0xA5://设置sim900波特率为9600
                        _CFGPHopedByteCounts = 0;
                        break;
                    case 0xA3://获取离线数据
                        _CFGPHopedByteCounts = 4;
                        break; 
                    default:
                        _CFGPHopedByteCounts = 0;
                        return;
                    }

                }

                if(_UART3BufferPosition == _CFGPHopedByteCounts) //收到配置命令
                    _CommandReceived = 1;
                else
                    _UART3BufferPosition++;

            }
        }





}



/*************************************************
函数名称: ConfigHandler
功    能: 主程序中调用此函数，用来处理用户从232口发来的配置命令
参    数: 无
返 回 值: 无
*************************************************/
int ConfigHandler()
{

    u16  i = 0;
    u16  j = 0;
    u16  k = 0;
    u16  l = 0;
    u32  u32Temp;
    u8   okstr[] = "OK\r\n";
    u8   errorstr[] = "ERROR\r\n";
 
    //进入配置模式
    //向PC发送字符串OK

 
 
    //等待PC端从串口发送的命令
WaitCommand:
    _CommandReceived = 0;
    memset(_UART3Buffer, '\0', sizeof(_UART3Buffer));
    _UART3BufferPosition = 0;
		
    while(1)
    {
        IWDG_Feed();
        if(_CommandReceived != 0)break;
    }

    //收到命令
    if(_CommandReceived != 0)
    {
       
        i = 0;

        if(_UART3Buffer[0] == 0xA0) //SETCFG
        {
            //参数设置

 			
					  memset(&_Config,'\0',sizeof(Config));
					//数据服务器ip
					  memcpy(&(_Config._ServerIP),&(_UART3Buffer[1]),16); 
					//数据服务器端口
					  memcpy(&(_Config._ServerPort),&(_UART3Buffer[17]),6);
 

            //采集间隔
            _Config._collectInterval = _UART3Buffer[23] << 8;
            _Config._collectInterval += _UART3Buffer[24];

            //设备编号
						 memcpy(&(_Config._DeviceNumber),&(_UART3Buffer[25]),16);
				 
            //时间设置
            RTC_Set(2000 + _UART3Buffer[41], _UART3Buffer[42], _UART3Buffer[43],
            _UART3Buffer[44], _UART3Buffer[45], _UART3Buffer[46]);
						
						//数据服务器域名
						 memcpy(&(_Config._ServerDN),&(_UART3Buffer[47]),50);
						
						//高频设置
						 _Config._HighFreqConfig = _UART3Buffer[97] << 8;
            _Config._HighFreqConfig += _UART3Buffer[98];
						
						
						//低频设置
						_Config._LowFreqConfig = _UART3Buffer[99] << 8;
            _Config._LowFreqConfig += _UART3Buffer[100];
						
							//土温设置
						_Config._SoilTempConfig = _UART3Buffer[101] << 8;
            _Config._SoilTempConfig += _UART3Buffer[102];
						
							//高频延时
						 _Config._HighFreqDelaySpan = _UART3Buffer[103] << 8;
             _Config._HighFreqDelaySpan += _UART3Buffer[104];
						
						
						//低频延时
						_Config._LowFreqDelaySpan = _UART3Buffer[105] << 8;
            _Config._LowFreqDelaySpan += _UART3Buffer[106];
						
						//是否节能					 
						_Config._EnergySaving = _UART3Buffer[107] << 8;
            _Config._EnergySaving += _UART3Buffer[108];
						
						//升级服务器域名
						 memcpy(&(_Config._UpdateServerDN),&(_UART3Buffer[109]),50);
 
 
						//升级服务器端口
						memcpy(&(_Config._UpdateServerPort),&(_UART3Buffer[159]),6);
						
						  //1-8层土温地址
            //bytesToSend[165] = byte.Parse(tbxSoilTempAddr1_8.Text);
							_Config.SoilTempAddr1_8 =_UART3Buffer[165];

            //9-16层土温地址
            //bytesToSend[166] = byte.Parse(tbxSoilTempAddr9_16.Text);
						_Config.SoilTempAddr9_16=_UART3Buffer[166];

            //是否新式土温
            //bytesToSend[168] = 0;
            //bytesToSend[168] = (byte)(cbxIsNewSoilTemp.Checked ? 1 : 0);
						_Config.IsNewSoilTemp=_UART3Buffer[168];
						
						
            //将配置保存到flash
						
						 
							STMFLASH_Write(FLASH_CFG_BASE_ADDR,(u16*)&_Config,(sizeof(_Config) /2));
						
			
					 



						//升级服务器域名和端口号

          
             printf("%s",okstr);
 
            goto WaitCommand;
        }

        /////////////////////////////////////////////////////////////////////////////
        if(_UART3Buffer[0] == 0xA1) //"GETCFG"
        {
            //参数读取
            memset(_UART3Buffer, '\0', sizeof(_UART3Buffer));
            //确保以'\0'结尾
            _Config._ServerIP[sizeof(_Config._ServerIP)-1] = 0;
            _Config._ServerPort[sizeof(_Config._ServerPort)-1] = 0;
					  _Config._ServerDN[sizeof(_Config._ServerDN)-1] = 0;
	//如果sprintf使用过长的参数堆栈会溢出，结果无法预料
            sprintf((char *)_UART3Buffer , "%s,%s,%s,%s,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%s,%s,%u,%u,%u\r\n",
                    _Config._ServerIP,
                    _Config._ServerPort,
							     	_Config._ServerDN,
					          _Config._DeviceNumber,
					
                    _Config._collectInterval,
                    _RecordCount,
                    _calendar.w_year,
                    _calendar.w_month,
                    _calendar.w_date,
                    _calendar.hour,
                    _calendar.min,
                    _calendar.sec,                    
                    _Config._HighFreqConfig,
										_Config._LowFreqConfig,
                    _Config._SoilTempConfig,
										_Config._HighFreqDelaySpan,
										_Config._LowFreqDelaySpan,
										_Config._EnergySaving,
						        _Config._UpdateServerDN,
						        _Config._UpdateServerPort,
										_Config.SoilTempAddr1_8,
										_Config.SoilTempAddr9_16,
										_Config.IsNewSoilTemp
						);

            j = StrLen(_UART3Buffer);


            for(i = 0; i < j; ++i)
            {

                USART_SendData(USART3, _UART3Buffer[i]);//向串口3发送数据
                while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET); //等待发送结束
            }
            goto WaitCommand;
        }


        //////////////////////////////////////////////////////////////////////////////////////
        if(_UART3Buffer[0] == 0xA2) //CLRDATA
        {
            //清除记录个数
            _RecordCount = 0;
            //写入记录个数
            u32Temp =	AT24CXX_Write(E2_CFG_ADDR_RECORDCOUNT, (u8 *)&_RecordCount, 2);
            if(u32Temp == 1)
            {

                for(i = 0; i < 4; i++)
                {
                    USART_SendData(USART3, okstr[i]);//向串口3发送数据
                    while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET); //等待发送结束
                }

            }
            else
            {

                for(i = 0; i < 7; i++)
                {
                    USART_SendData(USART3, errorstr[i]);//向串口3发送数据
                    while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET); //等待发送结束
                }
            }
            goto WaitCommand;
        }
				//////////////////////////////////////////////////////////////////////
         if(_UART3Buffer[0] == 0xA5) //SETSIM900BAUDRATE  设置sim900的波特率为9600
        {
					
				   	 u32Temp= PrepareCommand();
					   if(u32Temp == 0) 
						 {
               printf("SET BAUDRATE FAIL\r\n");
						 
						 }
						 else
						 {
							  //设置sim900的波特率为9600
                u32Temp = IPR();

                if(u32Temp == 1)            
                  printf("SET BAUDRATE SUCCESS\r\n");            
                else
                  printf("SET BAUDRATE FAIL\r\n");
             
					    }
            goto WaitCommand;
        }
        ////////////////////////////////////////////////////////////////////////////
        if(_UART3Buffer[0] == 0xA4) //RESETDEV
        {
            for(i = 0; i < 4; i++)
            {
                USART_SendData(USART3, okstr[i]);//向串口3发送数据
                while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET); //�̨���y����?��?����?
            }
            return 0;
        }

        ///////////////////////////////////////////////////////////////////
        if( _UART3Buffer[0] == 0xA3) //"GETDATA"))
        {
            //数据读取
            k = (_UART3Buffer[1] << 8) + _UART3Buffer[2]; //读取的起始索引
            l = (_UART3Buffer[3] << 8) + _UART3Buffer[4]; //要读取的记录个数

            memset(_UART3Buffer, '\0', sizeof(_UART3Buffer));				

            for(i = 0; i < l; ++i)
            {
                AT24CXX_Read(E2_DATA_BASE_ADDR + k * E2_RECORD_SIZE + i * E2_RECORD_SIZE, _UART3Buffer, E2_RECORD_SIZE);
                for(j = 0; j < E2_RECORD_SIZE; ++j)
                {
                    USART_SendData(USART3, _UART3Buffer[j]);//向串口3发送数据
                    while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET); //等待发送结束
                }
            }



            goto WaitCommand;
        }
       

        //////////////////////////////////////////////////////////////////////////////////////// 
        goto WaitCommand;
    }//if(_CommandReceived!=0)
    return 1;
}

 
/*************************************************
函数名称: LoadConfig
功    能: 从flash中加载用户配置
参    数: 无
返 回 值: 无
*************************************************/
void LoadConfig()
{
 
  
    memset(&_Config, '\0', sizeof(_Config)); 
    //从flash中读取所有的配置 
  	STMFLASH_Read(FLASH_CFG_BASE_ADDR,(u16*)(&_Config), sizeof(Config));	
	  DebugOut("Now it is the Version:%d\r\n",CURRENT_FIRMWARE_VERSION);
		DebugOut("IP:%s\r\n",_Config._ServerIP); 
		DebugOut("Port:%s\r\n", _Config._ServerPort);
		DebugOut("CollectInterval:%d\r\n", _Config._collectInterval);
		DebugOut("DeviceNumber:%s\r\n", _Config._DeviceNumber);
		DebugOut("Server domain name:%s\r\n", _Config._ServerDN);
    //高频设置
		DebugOut("CopperRing high frequency Config:%X\r\n", _Config._HighFreqConfig);
   //低频设置
		DebugOut("CopperRing low frequency Config:%X\r\n", _Config._LowFreqConfig);
    //土温设置
		DebugOut("Soil Temperature Config:%X\r\n", _Config._SoilTempConfig);
    //高频延时
		DebugOut("CopperRing high frequency delay :%X\r\n", _Config._HighFreqDelaySpan);
    //低频延时
		DebugOut("CopperRing low frequency delay:%X\r\n", _Config._LowFreqDelaySpan);
		//节能
		DebugOut("Energy saving:%X\r\n", _Config._EnergySaving);
		//
		DebugOut("Update Server domain name:%s\r\n",_Config._UpdateServerDN); 
		DebugOut("Update Server Port:%s\r\n", _Config._UpdateServerPort);
		 //1-8层土温地址
		DebugOut("The address of 1-8 level soil temperature :%X\r\n", _Config.SoilTempAddr1_8);
		 //9-16层土温地址
		DebugOut("The address of 9-16 level soil temperature :%X\r\n", _Config.SoilTempAddr9_16);
		//是否新式土温
		DebugOut("Is new soil temperature:%X\r\n", _Config.IsNewSoilTemp);
		
		
		
		//
    //离线记录个数仍然存储在24c256中
    AT24CXX_Read(E2_CFG_BASE_ADDR , (u8 *)&_RecordCount, E2_CFG_SIZE_RECORDCOUNT);
		if(_RecordCount>E2_MAX_RECORD_COUNT)
			_RecordCount=0;
    DebugOut("RecordCount:%d\r\n", _RecordCount);

}
#endif
